//
//  BoWWrapper.hpp
//  BoW
//
//  Created by CADCG on 16/4/23.
//  Copyright © 2016年 CADCG. All rights reserved.
//
//
#ifndef BoWWrapper_hpp
#define BoWWrapper_hpp

#include <stdio.h>



// DBoW2
#include "BowVector.h"
#include "FClass.h"
#include "FeatureVector.h"
#include "FORB.h"
#include "ScoringObject.h"
//#include "DUtils.h"
#include "TemplatedVocabulary.h"

// OpenCV
#include <opencv/cv.h>
#include <opencv/highgui.h>

#include <opencv2/nonfree/features2d.hpp>
#include <mutex>
#include "prosac.hpp"
//
//typedef DBoW2::TemplatedDatabase<DBoW2::FORB::TDescriptor, DBoW2::FORB>
//ORBDatabase;

typedef struct _QueryResult
{
    size_t id;
    size_t nMatches;
    cv::Matx33d Htq;
}_QueryResult;

typedef std::vector<_QueryResult > QueryResult;

typedef DBoW2::TemplatedVocabulary<DBoW2::FORB::TDescriptor, DBoW2::FORB>
ORBVocabulary;

class BoWWrapperORB
{
public:

  BoWWrapperORB(int k=9,int L=3,const DBoW2::WeightingType &weight=DBoW2::TF_IDF,const DBoW2::ScoringType &score=DBoW2::L1_NORM):k_(k),L_(L),weight_(weight),score_(score){voc = ORBVocabulary(k_,L_,weight_,score_);};
  ~BoWWrapperORB(){};
    void addImages(const std::vector<std::vector<cv::KeyPoint> >&kpts,const std::vector<cv::Mat> &desps);
  void clear();
    void addImage(const std::vector<cv::KeyPoint>&kpts,const cv::Mat &desp);
  void train();
    QueryResult query(const std::vector<cv::KeyPoint>&kpts,const cv::Mat& desp);
  bool hasVoc(){return isTrained;};
private:
  std::mutex m;
  ORBVocabulary voc;
  int k_ = 9;
  int L_ = 3;
  DBoW2::WeightingType weight_ = DBoW2::TF_IDF;
  DBoW2::ScoringType score_ = DBoW2::L1_NORM;
  std::vector<vector<DBoW2::FORB::TDescriptor> > allDesp;
    void toDespVec(const cv::Mat&desp,std::vector<cv::Mat>&despVec);
    std::vector<DBoW2::BowVector> vBowVectors;
    std::vector<DBoW2::FeatureVector> vFeatureVectors;
    std::vector<std::vector<cv::KeyPoint>> allKeyPoints;
  //ORBDatabase db;
  bool isTrained = false;
};






#endif /* BoWWrapper_hpp */
